package yxy.cherry.gateway.internal;

import yxy.apple.logger.Logger;
import yxy.apple.protobuf.Constants;
import yxy.apple.protobuf.Message.Parcal;
import yxy.banana.server.internal.InternalClientBundler;
import yxy.banana.server.internal.InternalClientController;
import yxy.banana.socket.NetworkElement;
import yxy.cherry.gateway.Configuration;
import yxy.cherry.gateway.Reactor;
import yxy.cherry.gateway.external.GatewayServerController;
import yxy.cherry.gateway.external.GatewayServerHandler;

public class GatewayClientController extends InternalClientController<GatewayClientHandler> {

	private static final Logger logger = Logger.create(GatewayClientController.class);

	@Override
	public boolean control(Parcal parcal) throws Exception {
		if (parcal.getProto() == Constants.ControlProto.KickoutNotification) {
			NetworkElement sne = NetworkElement.assemble(parcal.getSource());
			NetworkElement dne = NetworkElement.assemble(parcal.getDestination());
			GatewayServerHandler external = Reactor.instance.externals().find(dne.channel());
			if (external != null) {
				GatewayServerController controller = (GatewayServerController) external.controller();
				controller.kick();
				logger.debug("应%s要求踢出的客户端连接%s...\r\n%s\r\n%s", sne, dne, this, external);
			} else {
				logger.warn("找不到%s要求踢出的客户端连接%s...\r\n%s", sne, dne, this);
			}
			return true;
		} else if (parcal.getProto() == Constants.ControlProto.ReplacedNotification) {
			NetworkElement sne = NetworkElement.assemble(parcal.getSource());
			NetworkElement dne = NetworkElement.assemble(parcal.getDestination());
			GatewayServerHandler external = Reactor.instance.externals().find(dne.channel());
			if (external != null) {
				GatewayServerController controller = (GatewayServerController) external.controller();
				controller.replace();
				logger.debug("应%s要求顶替客户端(uid: %d)连接%s...\r\n%s\r\n%s", sne, external.uid(), dne, this, external);
			} else {
				logger.warn("找不到%s要求顶替的客户端连接%s...\r\n%s", sne, dne, this.toString());
			}
			return true;
		} else {
			return false;
		}
	}

	@Override
	protected void announced(long delta) {
		logger.debug("client announced");
		super.announced(delta);
		if (delta >= Configuration.shared().InternalClient.HeartbeatResponseDelayAlertThreshold) {
			logger.info("收到心跳回应，链路延迟%d毫秒，延迟过大，请检查内部网络！\r\n%s", delta, this.toString());
			// TODO 推送警告给运维
			// TODO 阈值可配置
		}
	}

	@Override
	protected void silenced(int times) {
		logger.debug("client silenced");
		super.silenced(times);
		// TODO 推送警告给运维
	}

	@Override
	protected int getHeartbeatInterval() {
		logger.debug("client getHeartbeatInterval");
		return Configuration.shared().InternalClient.HeartbeatInterval;
	}

	@Override
	protected int getHeartbeatResponseTimeout() {
		return Configuration.shared().InternalClient.HeartbeatResponseTimeout;
	}

	@Override
	protected int getRegistryResponseTimeout() {
		return Configuration.shared().InternalClient.RegistryResponseTimeout;
	}

	@Override
	protected InternalClientBundler<GatewayClientHandler> bundler() {
		return Reactor.instance.internals();
	}

}
